#include "FFmpegKits.h"
#include <QDebug>
#include <QElapsedTimer>
#include <QDateTime>

FFmpegKits::FFmpegKits(QObject *parent) : QObject(parent)
{
    // 初始化FFmpeg网络库（如果需要）
    avformat_network_init();
}

FFmpegKits::~FFmpegKits()
{
    qDebug() << "销毁FFmpegKits对象";
    cleanup();
    avformat_network_deinit();
    qDebug() << "FFmpegKits对象已销毁";
}

bool FFmpegKits::initDecoder(const VideoMetadata& metadata)
{
    QMutexLocker locker(&m_mutex);

    // 先清理现有资源
    cleanup();

    // 验证元数据有效性
    if (metadata.width <= 0 || metadata.height <= 0) {
        qWarning() << "无效的视频尺寸:" << metadata.width << "x" << metadata.height;
        return false;
    }

    if (metadata.codecId <= 0) {
        qWarning() << "无效的编解码器ID:" << metadata.codecId;
        return false;
    }

    // 保存尺寸信息
    m_width = metadata.width;
    m_height = metadata.height;

    // 查找解码器
    m_pCodec = avcodec_find_decoder(static_cast<AVCodecID>(metadata.codecId));
    if (!m_pCodec) {
        qWarning() << "找不到编解码器，ID:" << metadata.codecId;
        return false;
    }

    // 创建解码器上下文
    m_pCodecCtx = avcodec_alloc_context3(m_pCodec);
    if (!m_pCodecCtx) {
        qWarning() << "无法分配解码器上下文";
        return false;
    }

    // 设置解码器参数
    m_pCodecCtx->width = metadata.width;
    m_pCodecCtx->height = metadata.height;
    m_pCodecCtx->codec_id = static_cast<AVCodecID>(metadata.codecId);
    m_pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;

    // 设置时间基
    m_pCodecCtx->time_base.num = metadata.timeBaseNum;
    m_pCodecCtx->time_base.den = metadata.timeBaseDen;

    // 设置extradata (SPS/PPS)
    if (!metadata.spsPps.isEmpty() && metadata.spsPps.size() > 0) {
        m_pCodecCtx->extradata_size = metadata.spsPps.size();
        m_pCodecCtx->extradata = (uint8_t*)av_malloc(metadata.spsPps.size() + AV_INPUT_BUFFER_PADDING_SIZE);
        if (m_pCodecCtx->extradata) {
            memcpy(m_pCodecCtx->extradata, metadata.spsPps.constData(), metadata.spsPps.size());
            memset(m_pCodecCtx->extradata + metadata.spsPps.size(), 0, AV_INPUT_BUFFER_PADDING_SIZE);
        } else {
            qWarning() << "无法分配extradata内存";
        }
    } else {
        qWarning() << "SPS/PPS数据为空或无效";
    }

    // 对于H.264编码，设置正确的像素格式
    if (metadata.codecId == AV_CODEC_ID_H264) {
        // H.264通常输出YUV420P格式
        m_pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
    }

    // 打开解码器
    if (avcodec_open2(m_pCodecCtx, m_pCodec, nullptr) < 0) {
        qWarning() << "无法打开解码器";
        return false;
    }

    // 获取实际的像素格式
    AVPixelFormat src_pix_fmt = m_pCodecCtx->pix_fmt;
    if (src_pix_fmt == AV_PIX_FMT_NONE) {
        // 如果解码器没有提供像素格式，使用H.264的默认格式
        src_pix_fmt = AV_PIX_FMT_YUV420P;
        qWarning() << "解码器返回无效像素格式，使用默认YUV420P";
    }

    qDebug() << "解码器像素格式:" << av_get_pix_fmt_name(src_pix_fmt);

    // 创建格式转换上下文
    m_pImgConvertCtx = sws_getContext(
                m_pCodecCtx->width, m_pCodecCtx->height, src_pix_fmt,
                m_pCodecCtx->width, m_pCodecCtx->height, AV_PIX_FMT_RGB32,
                SWS_BICUBIC, nullptr, nullptr, nullptr
                );

    if (!m_pImgConvertCtx) {
        qWarning() << "无法创建图像转换上下文";
        return false;
    }

    // 分配帧
    m_pFrameYUV = av_frame_alloc();
    m_pFrameRGB = av_frame_alloc();

    if (!m_pFrameYUV || !m_pFrameRGB) {
        qWarning() << "无法分配帧";
        return false;
    }

    // 分配输出缓冲区
    int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB32, m_pCodecCtx->width, m_pCodecCtx->height, 1);
    m_pOutBuffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
    if (!m_pOutBuffer) {
        qWarning() << "无法分配输出缓冲区";
        return false;
    }

    // 设置RGB帧参数
    av_image_fill_arrays(
                m_pFrameRGB->data, m_pFrameRGB->linesize,
                m_pOutBuffer, AV_PIX_FMT_RGB32,
                m_pCodecCtx->width, m_pCodecCtx->height, 1
                );

    m_initialized = true;
    qDebug() << "解码器初始化完成";
    return true;
}

void FFmpegKits::decodeVideoFrame(const VideoFrame& frame) {
    QMutexLocker locker(&m_mutex);

    if (!m_initialized) {
        qWarning() << "解码器未初始化，无法解码帧";
        return;
    }

    // 增加帧数据验证
    if (frame.data.isEmpty() || frame.size <= 0) {
        qWarning() << "无效的视频帧数据，大小:" << frame.size;
        return;
    }

    qDebug() << "开始解码视频帧 - 大小:" << frame.size << "，PTS:" << frame.pts;

    // 创建AVPacket
    AVPacket* pkt = av_packet_alloc();
    if (!pkt) {
        qWarning() << "无法分配AVPacket";
        return;
    }

    // 复制帧数据
    pkt->data = (uint8_t*)av_malloc(frame.data.size());
    if (!pkt->data) {
        qWarning() << "无法分配视频帧数据缓冲区";
        av_packet_free(&pkt);
        return;
    }

    memcpy(pkt->data, frame.data.constData(), frame.data.size());
    pkt->size = frame.data.size();
    pkt->pts = frame.pts;
    pkt->dts = frame.dts;

    // 发送到解码器
    int ret = avcodec_send_packet(m_pCodecCtx, pkt);
    if (ret < 0) {
        char errorBuf[AV_ERROR_MAX_STRING_SIZE];
        av_strerror(ret, errorBuf, sizeof(errorBuf));
        qWarning() << "发送数据包到解码器失败:" << errorBuf;
        av_packet_free(&pkt);
        return;
    }

    // 接收解码后的帧
    while (ret >= 0) {
        ret = avcodec_receive_frame(m_pCodecCtx, m_pFrameYUV);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
            break;
        } else if (ret < 0) {
            char errorBuf[AV_ERROR_MAX_STRING_SIZE];
            av_strerror(ret, errorBuf, sizeof(errorBuf));
            qWarning() << "解码错误:" << errorBuf;
            break;
        }

        qDebug() << "成功解码一帧，准备转换格式";

        // 转换YUV到RGB
        sws_scale(
            m_pImgConvertCtx,
            (const uint8_t* const*)m_pFrameYUV->data,
            m_pFrameYUV->linesize,
            0, m_pCodecCtx->height,
            m_pFrameRGB->data, m_pFrameRGB->linesize
        );

        // 创建QImage并发送
        QImage tmpImg(
            m_pOutBuffer,
            m_pCodecCtx->width,
            m_pCodecCtx->height,
            QImage::Format_RGB32
        );

        if (!tmpImg.isNull()) {
            qDebug() << "生成有效图像，尺寸:" << tmpImg.size() << "，发送到UI";
            emit sigGetOneFrame(tmpImg.copy());
        } else {
            qWarning() << "解码后的图像为空";
        }

        av_frame_unref(m_pFrameYUV);
    }

    av_packet_free(&pkt);
    qDebug() << "视频帧解码完成";
}
void FFmpegKits::cleanup()
{
    if (m_pOutBuffer) {
        av_free(m_pOutBuffer);
        m_pOutBuffer = nullptr;
    }
    if (m_pImgConvertCtx) {
        sws_freeContext(m_pImgConvertCtx);
        m_pImgConvertCtx = nullptr;
    }
    if (m_pFrameRGB) {
        av_frame_free(&m_pFrameRGB);
        m_pFrameRGB = nullptr;
    }
    if (m_pFrameYUV) {
        av_frame_free(&m_pFrameYUV);
        m_pFrameYUV = nullptr;
    }
    if (m_pCodecCtx) {
        avcodec_close(m_pCodecCtx);
        avcodec_free_context(&m_pCodecCtx);
        m_pCodecCtx = nullptr;
    }

    m_initialized = false;
    qDebug() << "FFmpeg资源已清理";
}

void FFmpegKits::onMetadataReceived(const VideoMetadata& metadata)
{
    qDebug() << "接收到视频元数据，摄像头ID:" << metadata.cameraId
             << "，分辨率:" << metadata.width << "x" << metadata.height;
    
    // 打印元数据详情用于调试
    qDebug() << "编解码器ID:" << metadata.codecId
             << "，时间基:" << metadata.timeBaseNum << "/" << metadata.timeBaseDen
             << "，SPS/PPS大小:" << metadata.spsPps.size() << "字节";

    // 初始化解码器
    if (!initDecoder(metadata)) {
        emit sigPlayError("解码器初始化失败");
    }
}

void FFmpegKits::onVideoFrameReceived(const VideoFrame& frame)
{
    // 解码视频帧
    decodeVideoFrame(frame);
}
